#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <conio.h>

#define WIDTH 20  // 定义游戏背景的宽度（列数）
#define HEIGHT 20 // 定义游戏背景的高度（行数）

// 定义一个结构体，表示一个点
struct Point
{
    int x; // x对应的是列
    int y; // y对应的是行
};

// 定义一个枚举，表示运动方向
enum Direction
{
    Up,
    Down,
    Left,
    Right
};
BOOL isOverlap(int x,int y,struct Point *body,int bodyLength){
    //判断是否与身体重合
    for(int i=0;i<bodyLength;i++){
        if(x == body[i].x && y == body[i].y){
            return TRUE;
        }
    }
    return FALSE;
}

//判断位置是否与蛇身体重合
BOOL isOverlap(struct Point *food,struct Point *head,struct Point *body,int bodyLength){
    //判断是否与蛇头重合
    if(food->x ==head->x && food->y == head->y){
        return TRUE;
    }
    return isOverlap(food->x,food->y,body,bodyLength);
}

// 打印当前帧的游戏画面
void printFrame(struct Point *food, struct Point *head,struct Point* body,int bodyLength)
{
    for (int i = 0; i < HEIGHT; i++) // 按行循环，i的值表示第几行
    {
        for (int j = 0; j < WIDTH; j++) // 按列循环，打印每一行的内容，j的值表示第几列
        {
            if (i == 0 || i == HEIGHT - 1 || j == 0 || j == WIDTH - 1)
            {
                // 第一行、最后一行、第一列、最后一列，显示为边框
                printf("#");
            }
            else if (i == food->y && j == food->x)
            {
                // food的显示
                printf("x");
            }
            else if (i == head->y && j == head->x)
            {
                // 打印“头”
                printf("o");
            }
            //判断是否与身体重合
            else if(isOverlap(j,i,body,bodyLength)){
                // 打印“身体”
                printf("*");
            }
            else
            {
                // 其它的位置都打印空格
                printf(" ");
            }
        }
        printf("\n"); // 打印换行符
    }
}

// 改变蛇头的位置
void moveHead(enum Direction direction, struct Point *head)
{
    switch (direction)
    {
    case Up: // 向上移动
        head->y--;
        break;
    case Down: // 向下移动
        head->y++;
        break;
    case Left: // 向左移动
        head->x--;
        break;
    case Right: // 向右移动
        head->x++;
        break;
    }
    // 如果移动到边框，从头开始显示
    if (head->y == HEIGHT - 1)
    {
        head->y = 1;
    }
    if (head->y == 0)
    {
        head->y = HEIGHT - 2;
    }
    if (head->x == WIDTH - 1)
    {
        head->x = 1;
    }

    if (head->x == 0)
    {
        head->x = WIDTH - 2;
    }
}

//改变移动方向
void changeDirection(enum Direction *direction)
{
    if (kbhit()) //判断是否有按键按下
    {
        switch (getch()) //获取第一个按下的按键值
        {
            case 'a':
            case 'A':
                *direction = Left;
                break;
            case 'd':
            case 'D':
                *direction = Right;
                break;
            case 'w':
            case 'W':
                *direction = Up;
                break;
            case 's':
            case 'S':
                *direction = Down;
                break;
        }
    }
}

//生成一个随机的点
struct Point randPoint(){
    struct Point food;
    food.x = 1 + rand() % (WIDTH - 2); // 通过rand函数，取随机数，并将值控制在 1~WIDTH-1 的范围内,rand函数在stdlib库中
    food.y = 1 + rand() % (HEIGHT - 2);
    return food;
}




//新增蛇的身体
void addBodyAndRefreshFood(struct Point *head,struct Point *food,struct Point *body,int* bodyLength){
    if(head->x != food->x || head->y != food->y){
        return;
    }

    (*bodyLength)++;
    //设置新增加的身体节点的位置为head的位置
    body[(*bodyLength)-1].x = head->x;
    body[(*bodyLength)-1].y = head->y;
    
    //刷新食物位置，如果与蛇的身体重叠则继续刷新
    do{
        *food = randPoint();
    }while (isOverlap(food,head,body,*bodyLength));
}

//移动身体
void moveBody(struct Point *head,struct Point *body,int bodyLength){
    for(int i = bodyLength-1;i>=0;i--){
        if(i==0){
            body[i].x = head->x;
            body[i].y = head->y;
        }else{
            body[i].x = body[i-1].x;
            body[i].y = body[i-1].y;
        }
    }
}

int main()
{
    // //定义食物
    // struct Point food = randPoint();

    // //定义头
    // struct Point head;
    // head.x = WIDTH / 2;
    // head.y = HEIGHT / 2;

    // //定义移动方向
    // enum Direction direction = Down;

    // // 获取当前控制台
    // HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    // // 获取当前光标信息
    // CONSOLE_CURSOR_INFO cursorInfo;
    // GetConsoleCursorInfo(hConsole, &cursorInfo);

    // // 设置光标不显示
    // cursorInfo.bVisible = FALSE;
    // SetConsoleCursorInfo(hConsole, &cursorInfo);

    // //定义一body数组，最大为占满可用游戏空间
    // struct Point body[(WIDTH - 2) * (HEIGHT-2)];

    // //定义身体长度，初始值为0
    // int bodyLength=0;

    // while (1)
    // {
    //     // 清除屏幕显示
    //     // system("cls");
    //     // 设置光标回到 0行 0列
    //     COORD coord = {0, 0}; // 0-based index
    //     SetConsoleCursorPosition(hConsole, coord);
    //     // 打印当前帧的 游戏画面
    //     printFrame(&food, &head,body,bodyLength);
    //     // 等待100毫秒
    //     Sleep(100);
    //     //移动蛇的身体
    //     moveBody(&head,body,bodyLength);
    //     //改变移动方向
    //     changeDirection(&direction);
    //     // 改变蛇头的位置
    //     moveHead(direction, &head);
    //     // 添加蛇的身体并刷新食物位置
    //     addBodyAndRefreshFood(&head,&food,body,&bodyLength);
    //     // 等待100毫秒
    //     Sleep(100);
    // }
    // return 0;

    int row = 10;
    int col=20;
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++)
        {
            if(i==0 || i==row-1){
                printf("*");
            }else{
                printf(" ");
            }
            
        }
        printf("\n");
    }
    return 0;
}
